package com.second.app.excutor;


import java.util.Date;
import java.util.concurrent.*;

/**
 * @Author GYZ
 * @Date 2024/1/26
 * <pre>
 *  自定义线程工厂，自定义线程池拒绝策略
 *  set/getRejectedExecutionHandler()
 * </pre>
 */

class MyThreadFactory implements ThreadFactory{

    @Override
    public Thread newThread(Runnable r) {
        Thread thread = new Thread(r);
        thread.setName("高红岩："+new Date());
        return thread;
    }
}
public class ExceptionHandler {
    public static void main(String[] args) {
        Runnable runnable = () -> {
            try {
                System.out.println(Thread.currentThread().getName() + " " + System.currentTimeMillis());
                Thread.sleep(4000);
                System.out.println(Thread.currentThread().getName() + " " + System.currentTimeMillis());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };
        ThreadPoolExecutor pool = new ThreadPoolExecutor(
                2,
                9999,
                9999L,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>());
        pool.setThreadFactory(new MyThreadFactory());
        pool.execute(runnable);

    }
}

//当线程运行出现异常时，则JDK抛出异常
class CustomExceptionTask{
    public static void main(String[] args) {
        Runnable runnable = () -> {
            System.out.println(Thread.currentThread().getName() + " " + System.currentTimeMillis());
            String abc = null;
            abc.indexOf(0);
            System.out.println(Thread.currentThread().getName() + " " + System.currentTimeMillis());
        };
        ThreadPoolExecutor pool = new ThreadPoolExecutor(
                2,
                9999,
                9999L,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>());
        pool.setThreadFactory(new MyThreadFactory());
        pool.execute(runnable);
    }
}
//所以在使用自定义线程工厂时，线程如果出现异常完全可以自定义处理的。
class MyThreadFactoryB implements ThreadFactory{

    @Override
    public Thread newThread(Runnable r) {
        Thread thread = new Thread(r);
        thread.setName("我的新名称："+new Date());
        thread.setUncaughtExceptionHandler((t, e) -> System.out.println("自定义处理异常使用："+t.getName()+" "+e.getMessage()));
        return thread;
    }
}
class CustomExceptionTaskResolve{
    public static void main(String[] args) {
        Runnable runnable = () -> {
            System.out.println(Thread.currentThread().getName() + " " + System.currentTimeMillis());
            String abc = null;
            abc.indexOf(0);
            System.out.println(Thread.currentThread().getName() + " " + System.currentTimeMillis());
        };
        ThreadPoolExecutor pool = new ThreadPoolExecutor(
                2,
                9999,
                9999L,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>());
        pool.setThreadFactory(new MyThreadFactoryB());
        pool.execute(runnable);
    }
}

class My1Runnable implements Runnable{

    private String userName;

    public My1Runnable(String userName){
        this.userName =userName;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    @Override
    public void run() {
        try {
            System.out.println(Thread.currentThread().getName()+" "+System.currentTimeMillis());
            Thread.sleep(4000);
            System.out.println(Thread.currentThread().getName()+" "+System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class MyCustomRejectedExecutionHandler implements RejectedExecutionHandler {

    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        System.out.println(((My1Runnable) r).getUserName()+" 被拒绝执行");
    }
}

class Test1{
    public static void main(String[] args) {
        My1Runnable my1Runnable1 = new My1Runnable("中国1");
        My1Runnable my1Runnable2 = new My1Runnable("中国2");
        My1Runnable my1Runnable3 = new My1Runnable("中国3");
        My1Runnable my1Runnable4 = new My1Runnable("中国4");

        ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 3,
                9999L, TimeUnit.SECONDS, new SynchronousQueue<>());
        pool.setRejectedExecutionHandler(new MyCustomRejectedExecutionHandler());
        pool.execute(my1Runnable1);
        pool.execute(my1Runnable2);
        pool.execute(my1Runnable3);
        pool.execute(my1Runnable4);
    }
}
